package com.io.thirdparties.aliyun

import android.content.Context
import com.alibaba.sdk.android.oss.*
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback
import com.alibaba.sdk.android.oss.common.auth.OSSAuthCredentialsProvider
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.io.commonlib.helper.LogHelper
import com.io.thirdparties.luban.IOnCompressListener
import com.io.thirdparties.luban.LubanHelper
import kotlinx.coroutines.*
import java.io.File

/**
 * 阿里云OSS文件上传工具类
 */
object AliyunOSSHelper : IOnCompressListener{
    private val TAG = AliyunOSSHelper::class.java.simpleName
    private var job: Job = Job()
    private var scope: CoroutineScope
    private var ossInstance: OSS? = null
    private var context: Context? = null

    //阿里云OSS :文件前缀： http://soonsmart.keji.io/
    //文件后缀"?x-oss-process=style/w288"
    private val ALI_OSS_BUCKET = "soon-smart"
    private val ALI_OSS_ENDPOINT = "https://oss-cn-qingdao.aliyuncs.com"
    private val ALI_OSS_STS_SERVER_URL =
        "https://api.mobile.soonsmart.keji.io/AliyunSTS/GetCredentials"
    private var ossCompletedCallback: OSSCompletedCallback<PutObjectRequest, PutObjectResult>? =
        null

    init {
        scope = CoroutineScope(job)
    }

    /**
     * 初始化方法调用一次就行，最好在Application进行
     */
    fun initAliOSS(ctx: Context, compressSize: Int = 10) {
        context = ctx
        if (ossInstance == null) {
            scope.launch(Dispatchers.IO) {
                val credentialProvider: OSSCredentialProvider =
                    OSSAuthCredentialsProvider(ALI_OSS_STS_SERVER_URL)
                val conf = ClientConfiguration()
                conf.connectionTimeout = 5 * 1000 // 连接超时，默认15秒。
                conf.socketTimeout = 5 * 1000 // socket超时，默认15秒。
                conf.maxConcurrentRequest = 5 // 最大并发请求数，默认5个。
                conf.maxErrorRetry = 1 // 失败后最大重试次数，默认2次。
                ossInstance = OSSClient(context, ALI_OSS_ENDPOINT, credentialProvider)
            }
        }
        if(compressSize > 0){
            LubanHelper.setMinSizeLuban(compressSize)
        }
    }

    /**
     * 设置上传文件结束后的回调
     */
    fun setOSSCompletedCallback(ossCompletedCallback: OSSCompletedCallback<PutObjectRequest, PutObjectResult>?) {
        this.ossCompletedCallback = ossCompletedCallback
    }

    /**
     * 上传本地文件到阿里云OSS
     * localFilePath:本地文件全路径
     * newFileName:新文件名
     * 上传图片前需要先压缩
     */
    fun uploadFileToAliOss(localFilePath: String, newFileName: String) {
        LogHelper.d(TAG, "uploadFileToAliOss--本地路径：${localFilePath}")
        context?.let {
            myNewFileName = newFileName
            LubanHelper.compressImgByLuban(it, localFilePath, this)
        }

    }

    private var myNewFileName = ""

    // region ----------------------------实现Luban的OnCompressListener接口的方法-------------------------
    override fun onStart() {
    }

    override fun onSuccess(file: File?) {
        LogHelper.d(TAG, "onSuccess--本地路径：${file?.absolutePath}")
        if (ossInstance != null && ossCompletedCallback != null) {
            scope.launch(Dispatchers.IO) {
                val put = PutObjectRequest(ALI_OSS_BUCKET, myNewFileName, file?.absolutePath)
                val task = ossInstance?.asyncPutObject(put, ossCompletedCallback)
            }
        } else {
            LogHelper.d(TAG, "uploadFileToAliOss--oss实例为空或者回调为空")
        }
    }

    override fun onError(e: Throwable?) {
        e?.let {
            LogHelper.d(TAG, "图片压缩失败--${it.message}")
        }
    }
    //endregion----------------------------实现Luban的OnCompressListener接口的方法---------------end----------
}